package asia.yuanding.wechat.web.netty.handler;

import asia.yuanding.wechat.web.netty.handler.annotation.MessageProcessor;
import asia.yuanding.wechat.web.netty.handler.annotation.NettyMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息调度器
 * 负责扫描和管理所有带有@NettyMessageHandler注解的处理类
 * 并根据消息类型调度到相应的处理方法
 * 
 * @author Kiro
 */
@Slf4j
@Component
public class MessageDispatcher implements ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;
    
    /**
     * 存储消息类型与处理方法的映射关系
     * Key: 消息类型, Value: 处理方法信息列表（按优先级排序）
     */
    private final Map<String, List<ProcessorMethod>> messageProcessorMap = new ConcurrentHashMap<>();
    
    /**
     * 存储处理器实例
     * Key: 处理器名称, Value: 处理器实例
     */
    private final Map<String, Object> handlerInstanceMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        scanAndRegisterHandlers();
        log.info("消息调度器初始化完成，共注册 {} 个处理器，{} 种消息类型", 
                handlerInstanceMap.size(), messageProcessorMap.size());
    }

    /**
     * 扫描并注册所有消息处理器
     */
    private void scanAndRegisterHandlers() {
        // 获取所有带有@NettyMessageHandler注解的Bean
        Map<String, Object> handlerBeans = applicationContext.getBeansWithAnnotation(NettyMessageHandler.class);
        
        for (Map.Entry<String, Object> entry : handlerBeans.entrySet()) {
            String beanName = entry.getKey();
            Object handlerInstance = entry.getValue();
            
            registerHandler(beanName, handlerInstance);
        }
    }

    /**
     * 注册单个处理器
     */
    private void registerHandler(String beanName, Object handlerInstance) {
        Class<?> handlerClass = handlerInstance.getClass();
        NettyMessageHandler handlerAnnotation = handlerClass.getAnnotation(NettyMessageHandler.class);
        
        if (handlerAnnotation == null) {
            return;
        }
        
        // 获取处理器类型（一级分类）
        String handlerType = handlerAnnotation.value();
        
        // 存储处理器实例
        handlerInstanceMap.put(handlerType, handlerInstance);
        
        // 扫描处理方法
        Method[] methods = handlerClass.getDeclaredMethods();
        for (Method method : methods) {
            MessageProcessor processorAnnotation = method.getAnnotation(MessageProcessor.class);
            if (processorAnnotation != null) {
                registerProcessorMethod(handlerType, handlerInstance, method, processorAnnotation);
            }
        }
        
        log.info("注册消息处理器: {}", handlerType);
    }

    /**
     * 注册处理方法
     */
    private void registerProcessorMethod(String handlerType, Object handlerInstance, Method method, MessageProcessor annotation) {
        String methodName = annotation.value();
        
        // 构建完整的消息类型：handlerType.methodName
        String messageType = handlerType + "." + methodName;
        
        ProcessorMethod processorMethod = new ProcessorMethod(
                handlerInstance, method, annotation.priority(), 
                annotation.async(), ""
        );
        
        // 按消息类型分组存储
        messageProcessorMap.computeIfAbsent(messageType, k -> new ArrayList<>()).add(processorMethod);
        
        // 按优先级排序（数值越小优先级越高）
        messageProcessorMap.get(messageType).sort(Comparator.comparingInt(ProcessorMethod::getPriority));
        
        log.debug("注册处理方法: {} -> {}.{} (优先级: {}, 异步: {})", 
                messageType, handlerInstance.getClass().getSimpleName(), 
                method.getName(), annotation.priority(), annotation.async());
    }

    /**
     * 调度消息到相应的处理方法
     * 
     * @param messageType 消息类型
     * @param message 消息内容
     * @param params 额外参数
     * @return 处理结果
     */
    public Object dispatch(String messageType, Object message, Object... params) {
        List<ProcessorMethod> processors = messageProcessorMap.get(messageType);
        if (processors == null || processors.isEmpty()) {
            log.warn("未找到消息类型 {} 的处理器", messageType);
            return null;
        }
        
        // 使用第一个处理器（优先级最高）
        ProcessorMethod processor = processors.get(0);
        
        try {
            if (processor.isAsync()) {
                // 异步处理
                return CompletableFuture.supplyAsync(() -> {
                    try {
                        return invokeMethod(processor, message, params);
                    } catch (Exception e) {
                        log.error("异步处理消息失败: messageType={}, error={}", messageType, e.getMessage(), e);
                        return null;
                    }
                });
            } else {
                // 同步处理
                return invokeMethod(processor, message, params);
            }
        } catch (Exception e) {
            log.error("处理消息失败: messageType={}, error={}", messageType, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 调用处理方法
     */
    private Object invokeMethod(ProcessorMethod processor, Object message, Object... params) throws Exception {
        Method method = processor.getMethod();
        Object instance = processor.getHandlerInstance();
        
        // 构建方法参数
        Object[] methodArgs = buildMethodArgs(method, message, params);
        
        // 调用方法
        method.setAccessible(true);
        return method.invoke(instance, methodArgs);
    }

    /**
     * 构建方法参数
     */
    private Object[] buildMethodArgs(Method method, Object message, Object... params) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object[] args = new Object[parameterTypes.length];
        
        // 简单的参数匹配策略
        int paramIndex = 0;
        for (int i = 0; i < parameterTypes.length; i++) {
            if (i == 0) {
                // 第一个参数通常是消息内容
                args[i] = message;
            } else if (paramIndex < params.length) {
                // 其他参数从params中获取
                args[i] = params[paramIndex++];
            } else {
                // 参数不足时设为null
                args[i] = null;
            }
        }
        
        return args;
    }

    /**
     * 获取所有已注册的处理器
     */
    public Map<String, Object> getAllHandlers() {
        return new HashMap<>(handlerInstanceMap);
    }

    /**
     * 获取指定消息类型的处理器数量
     */
    public int getProcessorCount(String messageType) {
        List<ProcessorMethod> processors = messageProcessorMap.get(messageType);
        return processors != null ? processors.size() : 0;
    }

    /**
     * 获取所有支持的消息类型
     */
    public Set<String> getSupportedMessageTypes() {
        return new HashSet<>(messageProcessorMap.keySet());
    }

    /**
     * 处理方法信息封装类
     */
    private static class ProcessorMethod {
        private final Object handlerInstance;
        private final Method method;
        private final int priority;
        private final boolean async;
        private final String description;

        public ProcessorMethod(Object handlerInstance, Method method, int priority, boolean async, String description) {
            this.handlerInstance = handlerInstance;
            this.method = method;
            this.priority = priority;
            this.async = async;
            this.description = description;
        }

        public Object getHandlerInstance() { return handlerInstance; }
        public Method getMethod() { return method; }
        public int getPriority() { return priority; }
        public boolean isAsync() { return async; }
        public String getDescription() { return description; }
    }
}